VFG.MeasureTriangle = function(viewer) {
	this.viewer = viewer;
	this.trianglesEntity = new Cesium.Entity();
	this.tempLineEntity = new Cesium.Entity();
	this.tempLineEntity2 = new Cesium.Entity();
	this.positions = [];
	this.tempPoints = [];
	this.tempPoints2 = [];
	this.entitys = [];
	this.tip = new VFG.Tip(this.viewer);
	this.init();
}

VFG.MeasureTriangle.prototype.init = function() {
	var _this = this;
	this.handler = new Cesium.ScreenSpaceEventHandler(_this.viewer.scene.canvas);
	this.handler.setInputAction(function(movement) {
		_this.tip.showAt(movement.endPosition, "单击开始，右击结束");
		//var position = _this.getCatesian3FromPX(movement.endPosition);
		var position = VFG.Util.getScreenToC3(_this.viewer, movement.endPosition, null);
		if (position && _this.positions.length > 0) {
			_this.tip.showAt(movement.endPosition, "再次点击结束");
			_this.positions.pop();
			_this.positions.push(position.clone());
			let horizontalPosition = _this.computesHorizontalLine(_this.positions);
			//高度
			_this.tempPoints.pop();
			_this.tempPoints.push(horizontalPosition.clone());
			//水平线
			_this.tempPoints2.pop();
			_this.tempPoints2.pop();
			_this.tempPoints2.push(position.clone())
			_this.tempPoints2.push(horizontalPosition.clone());
		} else {
		}
	}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

	this.handler.setInputAction(function(movement) {
		//var position = _this.getCatesian3FromPX(movement.position);
		var position = VFG.Util.getScreenToC3(_this.viewer, movement.position, null);
		if (!position && !position.z) return false;
		if (_this.positions.length == 0) {
			_this.positions.push(position.clone());
			_this.positions.push(position.clone());
			_this.tempPoints.push(position.clone());
			_this.tempPoints.push(position.clone());
		} else {
			_this.stop();
			if(_this.success){
				_this.success();
			}
		}
	}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
	_this.addEntity();
}

VFG.MeasureTriangle.prototype.addEntity = function() {
	var _this = this;
	//直线
	_this.trianglesEntity.polyline = {
		positions: new Cesium.CallbackProperty(function() {
			return _this.positions
		}, false),
		width: 3,
		clampToGround: false,
		classificationType: Cesium.ClassificationType.BOTH,
		material: new Cesium.PolylineGlowMaterialProperty({
	 		glowPower : 0.5,
	  		color : Cesium.Color.fromCssColorString('#ffff00'),
		}),
	}
	_this.trianglesEntity.position = new Cesium.CallbackProperty(function() {
		return _this.positions[0]
	}, false)
	_this.trianglesEntity.point = {
		pixelSize: 5,
		color: Cesium.Color.RED,
		outlineColor: Cesium.Color.WHITE,
		outlineWidth: 2,
	}
	_this.trianglesEntity.label = {
		text: new Cesium.CallbackProperty(function() {
			return '直线:' + _this.getPositionDistance(_this.transformCartesianArrayToWGS84Array(_this.positions)) + '米'
		}, false),
		show: true,
		showBackground: true,
		font: '14px monospace',
		horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
		verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
		pixelOffset: new Cesium.Cartesian2(50, -100) //left top
	}
	//高度
	_this.tempLineEntity.polyline = {
		positions: new Cesium.CallbackProperty(function() {
			return _this.tempPoints
		}, false),
		width: 3,
		clampToGround: false,
		classificationType: Cesium.ClassificationType.BOTH,
        material: new Cesium.PolylineGlowMaterialProperty({
	 		glowPower : 0.5,
	  		color : Cesium.Color.fromCssColorString('#ffff00'),
		}),
	}
	_this.tempLineEntity.position = new Cesium.CallbackProperty(function() {
		return _this.tempPoints2[1]
	}, false)
	_this.tempLineEntity.point = {
		pixelSize: 5,
		color: Cesium.Color.RED,
		outlineColor: Cesium.Color.WHITE,
		outlineWidth: 2,
	}
	_this.tempLineEntity.label = {
		text: new Cesium.CallbackProperty(function() {
			return '高度:' + _this.getHeading(_this.tempPoints[0], _this.tempPoints[1]) + '米'
		}, false),
		show: true,
		showBackground: true,
		font: '14px monospace',
		horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
		verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
		pixelOffset: new Cesium.Cartesian2(-20, 100) //left top
	}
	//水平
	_this.tempLineEntity2.polyline = {
		positions: new Cesium.CallbackProperty(function() {
			return _this.tempPoints2
		}, false),
		width: 3,
		clampToGround: false,
		classificationType: Cesium.ClassificationType.BOTH,
        material: new Cesium.PolylineGlowMaterialProperty({
	 		glowPower : 0.5,
	  		color : Cesium.Color.fromCssColorString('#ffff00'),
		}),
	}
	_this.tempLineEntity2.position = new Cesium.CallbackProperty(function() {
		return _this.positions[1]
	}, false)
	_this.tempLineEntity2.point = {
		pixelSize: 5,
		color: Cesium.Color.RED,
		outlineColor: Cesium.Color.WHITE,
		outlineWidth: 2,
	}
	_this.tempLineEntity2.label = {
		text: new Cesium.CallbackProperty(function() {
			return '水平距离:' + _this.getPositionDistance(_this.transformCartesianArrayToWGS84Array(_this.tempPoints2)) + '米'
		}, false),
		show: true,
		showBackground: true,
		font: '14px monospace',
		horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
		verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
		pixelOffset: new Cesium.Cartesian2(-150, -20) //left top
	}
	_this.entitys.push(_this.viewer.entities.add(_this.tempLineEntity2));
	_this.entitys.push(_this.viewer.entities.add(_this.tempLineEntity));
	_this.entitys.push(_this.viewer.entities.add(_this.trianglesEntity));
}

// 高度
VFG.MeasureTriangle.prototype.getHeading = function(startPosition, endPosition) {
	if (!startPosition && !endPosition) return 0
	if (Cesium.Cartesian3.equals(startPosition, endPosition)) return 0
	let cartographic = Cesium.Cartographic.fromCartesian(startPosition);
	let cartographic2 = Cesium.Cartographic.fromCartesian(endPosition);
	return (cartographic2.height - cartographic.height).toFixed(2)
}

// 偏移点
VFG.MeasureTriangle.prototype.computesHorizontalLine = function(positions) {
	let cartographic = Cesium.Cartographic.fromCartesian(positions[0]);
	let cartographic2 = Cesium.Cartographic.fromCartesian(positions[1]);
	return Cesium.Cartesian3.fromDegrees(
		Cesium.Math.toDegrees(cartographic.longitude),
		Cesium.Math.toDegrees(cartographic.latitude),
		cartographic2.height
	)
}

VFG.MeasureTriangle.prototype.transformCartesianArrayToWGS84Array = function(cartesianArr) {
	var _this = this;
	if (_this.viewer) {
		return cartesianArr ?
			cartesianArr.map(function(item) {
				return _this.transformCartesianToWGS84(item)
			}) : []
	}
}

VFG.MeasureTriangle.prototype.transformWGS84ToCartographic = function(position) {
	return position ?
		Cesium.Cartographic.fromDegrees(
			position.lng || position.lon,
			position.lat,
			position.alt
		) :
		Cesium.Cartographic.ZERO;
}

/***
 * 坐标转换 笛卡尔转84
 * 
 * @param {Object} Cartesian3 三维位置坐标
 * 
 * @return {Object} {lng,lat,alt} 地理坐标
 */
VFG.MeasureTriangle.prototype.transformCartesianToWGS84 = function(cartesian) {
	var _this = this;
	if (_this.viewer && cartesian) {
		var ellipsoid = Cesium.Ellipsoid.WGS84
		var cartographic = ellipsoid.cartesianToCartographic(cartesian)
		return {
			lng: Cesium.Math.toDegrees(cartographic.longitude),
			lat: Cesium.Math.toDegrees(cartographic.latitude),
			alt: cartographic.height
		}
	}
}

/**
 * 拾取位置点
 * @param {Object} px 屏幕坐标
 * @return {Object} Cartesian3 三维坐标
 */
VFG.MeasureTriangle.prototype.getCatesian3FromPX = function(px) {
	var _this = this;
	if (_this.viewer && px) {
		var picks = _this.viewer.scene.drillPick(px)
		var cartesian = null;
		var isOn3dtiles = false,
			isOnTerrain = false;
		// drillPick
		for (let i in picks) {
			let pick = picks[i]
			if (pick &&
				pick.primitive instanceof Cesium.Cesium3DTileFeature ||
				pick && pick.primitive instanceof Cesium.Cesium3DTileset ||
				pick && pick.primitive instanceof Cesium.Model) { //模型上拾取
				isOn3dtiles = true;
			}
			if (isOn3dtiles) {
				_this.viewer.scene.pick(px) // pick
				cartesian = _this.viewer.scene.pickPosition(px);
				if (cartesian) {
					let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
					if (cartographic.height < 0) cartographic.height = 0;
					let lon = Cesium.Math.toDegrees(cartographic.longitude),
						lat = Cesium.Math.toDegrees(cartographic.latitude),
						height = cartographic.height;
					cartesian = _this.transformWGS84ToCartesian({
						lng: lon,
						lat: lat,
						alt: height
					})

				}
			}
		}
		// 地形
		let boolTerrain = _this.viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider;
		// Terrain
		if (!isOn3dtiles && !boolTerrain) {
			var ray = _this.viewer.scene.camera.getPickRay(px);
			if (!ray) return null;
			cartesian = _this.viewer.scene.globe.pick(ray, _this.viewer.scene);
			isOnTerrain = true
		}
		// 地球
		if (!isOn3dtiles && !isOnTerrain && boolTerrain) {
			cartesian = _this.viewer.scene.camera.pickEllipsoid(px, _this.viewer.scene.globe.ellipsoid);
		}
		if (cartesian) {
			let position = _this.transformCartesianToWGS84(cartesian)
			if (position.alt < 0) {
				cartesian = _this.transformWGS84ToCartesian(position, 0.1)
			}
			return cartesian;
		}
		return false;
	}
}


/**
 * 获取84坐标的距离
 * @param {*} positions 
 */
VFG.MeasureTriangle.prototype.getPositionDistance = function(positions) {
	let distance = 0
	for (let i = 0; i < positions.length - 1; i++) {
		let point1cartographic = this.transformWGS84ToCartographic(positions[i])
		let point2cartographic = this.transformWGS84ToCartographic(positions[i + 1])
		let geodesic = new Cesium.EllipsoidGeodesic()
		geodesic.setEndPoints(point1cartographic, point2cartographic)
		let s = geodesic.surfaceDistance
		s = Math.sqrt(
			Math.pow(s, 2) +
			Math.pow(point2cartographic.height - point1cartographic.height, 2)
		)
		distance = distance + s
	}
	return distance.toFixed(3);
}


VFG.MeasureTriangle.prototype.addListener = function(callback) {
	if (callback != null) {
		this.success = callback;
	}
}

VFG.MeasureTriangle.prototype.removeListener = function() {
	this.success = null;
}

VFG.MeasureTriangle.prototype.stop = function() {
	if (this.tip) {
		this.tip.destroy();
	}
	if (this.handler) {
		this.handler.destroy();
		this.handler = null;
	};
}

VFG.MeasureTriangle.prototype.destroy = function() {
	var _this = this;
	if (this.tip) {
		this.tip.destroy();
	}
	if (this.handler) {
		this.handler.destroy();
		this.handler = null;
	};
	if (_this.entitys && _this.entitys.length > 0) {
		for (var i = 0; i < _this.entitys.length; i++) {
			this.viewer.entities.remove(_this.entitys[i]);
		}
	}
	delete this.handler
	delete this.viewer
	delete this.tempPoints
	delete this.trianglesEntity
	delete this.tempLineEntity
	delete this.tempLineEntity2
};

